home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / HyperCard Related / APDA HyperCard Toolkits / CD Audio Toolkit 1.0 / Source / CDProgram.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-07  |  7.4 KB  |  300 lines  |  [TEXT/MPS ]

  1. /*
  2.     CDProgram - An XFCN to read the table of contents of a CD
  3.     ©Apple Computer, Inc. 1988
  4.     All Rights Reserved.
  5.     
  6.     88/10/08    BL°B    First Version
  7.  
  8.     To compile and link this file using Macintosh Programmer's Workshop,
  9.  
  10.     C -q2 CDProgram.c
  11.     link -sn Main=CDProgram -sn STDIO=CDProgram ∂
  12.          -sn INTENV=CDProgram -rt XFCN=42 ∂
  13.          -m CDProgram CDProgram.c.o "{CLibraries}"CRuntime.o ∂
  14.          "{CLibraries}"StdCLib.o ∂
  15.          -o HyperCommands
  16.          
  17.     This link directive puts the XCMD in the file "HyperCommands".
  18.     Substitute the name of the stack you want it in.  To move XCMDs
  19.     between stacks, use ResEdit.  They can be in an individual stack,
  20.     the Home stack, the HyperCard application, or the System File.
  21.     
  22. */
  23.  
  24. #include <cd.h>
  25.  
  26. typedef struct {
  27.     long    trackNo;    /* in BCD */
  28.     long    playMode;    /* 0 = don't play, 1 = play */
  29. } ProGInfo, *ProGInfoPtr, **ProGInfoHandle;
  30.  
  31. /* prototype definitions for functions */
  32. OSErr    GetProG(unsigned long, short, ProGInfo *);
  33. OSErr    FindProGID(unsigned long, short *);
  34. void    CFormatString(char *, long *, long);
  35.  
  36. /* **** WARNING:  DO NOT USE GLOBAL VARIABLES! **** */
  37.  
  38.  
  39. /************************************************************************
  40.  *
  41.  *  Function:        CDProgram
  42.  *
  43.  *  Purpose:        Read program information from 'CD Remote Programs'
  44.  *
  45.  *  Returns:        OSErr
  46.  *                    normally 0, but could have parameter error or
  47.  *                    other error if problems
  48.  *
  49.  *  Side Effects:
  50.  *
  51.  *  Description:    We need no parameter:
  52.  *                    Get the ioRefNum that we got from previously calling
  53.  *                    CDOpen() by accessing the famous global.
  54.  *                    Get the ProG resource for this disc (if it exists)
  55.  *                    and convert it to a long series of items.  Each track
  56.  *                    gets two items returned
  57.  *                    1) whether to play the track or not
  58.  *                    2) the track number in sequence (since a user can
  59.  *                       change the sequence of tracks using command drag
  60.  *                       in the CD Remote desk accessory.)
  61.  *
  62.  ************************************************************************/
  63. pascal void
  64. CDProgram(paramPtr)
  65. XCmdBlockPtr    paramPtr;
  66. {
  67.     Str31    returnString;
  68.     OSErr    result;
  69.     short    ioRefNum;
  70.     Handle    refHandle;
  71.     unsigned long    discID;
  72.     short    numberTracks;
  73.     ProGInfoHandle    proGHandle;
  74.     
  75.     Handle    formatString;
  76.         
  77.     /* Must be no parameter */
  78.     if ((paramPtr->paramCount) != 0)
  79.     {
  80.         /* Report error in parameters by returning -1 */
  81.         NumToStr(paramPtr, (long) -1, &returnString);
  82.         paramPtr->returnValue = PasToZero(paramPtr, (StringPtr) &returnString);
  83.         return;
  84.     }
  85.     
  86.     /* Get the global ioRefNum and convert it. */
  87.     refHandle = GetGlobal(paramPtr, GLOBALNAME);
  88.     ioRefNum = atoi(*(refHandle));
  89.     DisposHandle(refHandle);
  90.     ioRefNum &= 0xFFFF;            /* remove vRefNum; not needed. */
  91.     
  92.     proGHandle = nil;        /* so final DisposHandle check will work */
  93.     
  94.     result = GetNumberTracks(ioRefNum, &numberTracks);
  95.     
  96.     if (result == noErr)
  97.     {
  98.         proGHandle = NewHandle(numberTracks * sizeof(ProGInfo));
  99.         if (proGHandle == nil)
  100.             result = MemError();
  101.         else
  102.             HLock(proGHandle);
  103.     }
  104.     
  105.     if (result == noErr)
  106.         result = IDDisc(ioRefNum, &discID);
  107.         
  108.     if (result == noErr)
  109.         result = GetProG(discID, numberTracks, *proGHandle);
  110.  
  111.     formatString = NewHandle(600);    /* we can have 99 tracks * 6 bytes per track */
  112.     if (formatString == nil)
  113.         result = MemError();
  114.  
  115.     if (result == noErr)
  116.     {
  117.         HLock(formatString);
  118.         CFormatString((char *)*formatString, *proGHandle, numberTracks * 2);
  119.         HUnlock(formatString);
  120.         paramPtr->returnValue = formatString;    /* let HyperCard do the dispose */
  121.     }
  122.     else
  123.     {
  124.         /* We had an error.  Convert result to string & return it */
  125.         NumToStr(paramPtr, (long) result, &returnString);
  126.         paramPtr->returnValue = PasToZero(paramPtr, (StringPtr) &returnString);
  127.         if (formatString != nil)
  128.             DisposHandle(formatString);    /* only dispose of this if we aren't */
  129.                                         /* returning it to Hypercard */
  130.     }
  131.  
  132.     if (proGHandle != nil)
  133.     {
  134.         HUnlock(proGHandle);
  135.         DisposHandle(proGHandle);
  136.     }
  137. }
  138.  
  139.  
  140. /************************************************************************
  141.  *
  142.  *  Function:        GetProG
  143.  *
  144.  *  Purpose:        Find ProG; allocate and fill in ProGInfo
  145.  *
  146.  *  Returns:        OSErr.  Usually noErr, but could have an error
  147.  *                    in opening the CD Remote Programs file.
  148.  *
  149.  *  Side Effects:    fills in ProGInfo with program info
  150.  *
  151.  *  Description:    open the file "CD Remote Programs".  Look at the
  152.  *                    'IndX' resource to find out if we have a program.
  153.  *                    If we can't find the appropriate 'IndX' resource,
  154.  *                    set return to -1 and return.  If we find
  155.  *                    the appropriate IndX resource, open the 'ProG'
  156.  *                    resource associated with this disc.  Loop through
  157.  *                    the 'ProG' resource to find the play mode and track
  158.  *                    number sequence.
  159.  *
  160.  ************************************************************************/
  161. OSErr
  162. GetProG(discID, numberTracks, pInfo)
  163. unsigned long    discID;
  164. short            numberTracks;
  165. ProGInfo        pInfo[];
  166. {
  167.     OSErr    result;
  168.     short    rsrcID;            /* holds the 'STR#' & 'ProG' resource id. */
  169.     short    resFile;
  170.     short    limit;
  171.     short    *prog;
  172.     Handle    progResource;
  173.     short    i;
  174.     Str255    fileName;
  175.     
  176.     result = noErr;
  177.     
  178.     GetIndString(fileName, STR_ID, DRIVENAME);
  179.     if (fileName == (Str255)0)
  180.         result = ResError();
  181.  
  182.     if (result == noErr)
  183.     {
  184.         resFile = OpenSystemResFile(fileName);
  185.         if (resFile == -1)
  186.             result = ResError();
  187.     }
  188.     
  189.     if (result == noErr)
  190.         result = FindProGID(discID, &rsrcID);
  191.     
  192.     if (rsrcID == 0 && result == noErr)
  193.     {
  194.         for (i = 1; i <= numberTracks; i++)
  195.         {
  196.             pInfo[i-1].playMode = 1;    /* fill in defaults */
  197.             pInfo[i-1].trackNo = i;
  198.         }
  199.     }
  200.     else
  201.     {
  202.         if (result == noErr)
  203.         {
  204.             progResource = Get1Resource('ProG', rsrcID);
  205.             if (progResource == nil)
  206.                 result = ResError();
  207.         }
  208.         
  209.         if (result == noErr)
  210.         {
  211.             prog = (short *) *progResource;
  212.             limit = prog[0];
  213.             if (limit != numberTracks)
  214.                 result = -1;    /* not really an OSErr; we'll check for it */
  215.             
  216.             for (i = 1; i <= limit; i++)
  217.             {
  218.                 pInfo[i-1].playMode = (long) (prog[i] >> 8) & 0x00FF;
  219.                 pInfo[i-1].trackNo = (long) BCD2DECIMAL(prog[i] & 0x00FF);
  220.             }
  221.         }
  222.     }
  223.     
  224.     CloseResFile(resFile);
  225.     return result;
  226. }
  227.  
  228.  
  229. /************************************************************************
  230.  *
  231.  *  Function:        FindProGID
  232.  *
  233.  *  Purpose:        Find ProG resource ID for this disc
  234.  *
  235.  *  Returns:        OSErr
  236.  *                    usually noErr, but if no IndX resource, will return
  237.  *                    ResError.
  238.  *
  239.  *  Side Effects:    fills in rsrcID
  240.  *
  241.  *  Description:    Assumes that we've already opened 'CD Remote Programs'
  242.  *                    file.  Find the IndX resource (famous value 128) and
  243.  *                    call FindIndex to find the ProG resource ID, if it
  244.  *                    exists.  If it doesn't exist, return noErr, but set
  245.  *                    rsrcID to 0.
  246.  *
  247.  ************************************************************************/
  248. OSErr
  249. FindProGID(discID, rsrcID)
  250. unsigned long    discID;
  251. short            *rsrcID;
  252. {
  253.     OSErr    result;
  254.     
  255.     result = noErr;
  256.         
  257.     if (result == noErr)
  258.         if (FindIndex(discID, rsrcID) != true)
  259.             *rsrcID = 0;
  260.     return result;
  261. }
  262.             
  263.  
  264.  
  265. /************************************************************************
  266.  *
  267.  *  Function:        CFormatString
  268.  *
  269.  *  Purpose:        prepare return string
  270.  *
  271.  *  Returns:        nothing
  272.  *
  273.  *  Side Effects:    creates C string from input parameters
  274.  *
  275.  *  Description:    For each of the numArgs values in num[], convert the 
  276.  *                    value to an ascii string and concatenate.
  277.  *
  278.  ************************************************************************/
  279. void
  280. CFormatString(str, num, numArgs)
  281. char    str[];
  282. long     num[];
  283. long    numArgs;
  284. {
  285.     short    i;
  286.     char    numStr[31];
  287.     
  288.     ltoa(num[0], str);
  289.     for (i = 1; i < numArgs; i++)
  290.     {
  291.         strcat(str, ",");        /* add comma to separate items */
  292.         ltoa(num[i], numStr);
  293.         strcat(str, numStr);
  294.     }
  295. }
  296.  
  297.  
  298. /* C routines for HyperCard callbacks */
  299. #include <XCmdGlue.inc.c>
  300.